package com.cn.ycy.controller;

import com.cn.ycy.dto.ResResult;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.DeferredResult;

import javax.websocket.server.PathParam;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Slf4j
@Controller
@RequestMapping("long")
public class LongpollingController {

    static Logger logger = LoggerFactory.getLogger(LongpollingController.class);

    @GetMapping("/call")
    @ResponseBody
    public DeferredResult<ResResult> call(@RequestParam(value = "delay") int delay) {
        // 线程 [http-nio-8081-exec-1]
        log.info("delay start -> {}",delay);

        // 泛型Object表示返回结果的类型
        DeferredResult<ResResult> resultDeferredResult = new DeferredResult<ResResult>(
                20000L, // 请求的超时时间
                new ResponseEntity<>(HttpStatus.NOT_MODIFIED)); // 超时后响应的结果

        // 线程 [http-nio-8081-exec-2]
        //注意 回调线程 跟 请求线程 不是同一个线程
        resultDeferredResult.onCompletion(new Runnable() {
            @Override
            public void run() {
                log.info("onCompletion");
            }
        });

        resultDeferredResult.onTimeout(new Runnable() {
            @Override
            public void run() {
                log.info("onTimeout");
            }
        });

        new Thread(() -> {
            try {
                //模拟耗时
                for (int j = 0; j < delay; j++) {
                    logger.warn("{},{} do work", Thread.currentThread().getName(), new Date());
                    Thread.sleep(1000);
                }
                resultDeferredResult.setResult(new ResResult("200", "sucess"));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

        log.info("delay end -> {}",delay);

        return resultDeferredResult;
    }

}
